package edu.guigu.appquickstart.utils;

import android.content.Context;
import android.os.Environment;
import android.util.Log;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import edu.guigu.appquickstart.R;

/**
* 外部文件操作工具类
* 权限：
*  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
*  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
*  android:requestLegacyExternalStorage="true"
 *
* @author Yuansir
* @since 2025/8/12 10:42
* @version V1.0
*/
public class ExternalFileUtils {

    private static final String TAG = "ExternalFileUtils";

    /**
     * 检查外部存储是否可用（可写）
     */
    public static boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state);
    }

    /**
     * 检查外部存储是否可读
     */
    public static boolean isExternalStorageReadable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state) ||
                Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
    }

    /**
     * 获取应用的公共文档目录
     *
     * @param context    上下文
     * @param folderName 自定义文件夹名称
     */
    public static File getPublicDocumentsDir(Context context, String folderName) {
        File docsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
        File appDir = new File(docsDir, context.getString(R.string.app_name));
        File customDir = new File(appDir, folderName);

        // 确保目录存在
        if (!customDir.exists()) {
            if (!customDir.mkdirs()) {
                Log.e(TAG, "Failed to create directory: " + customDir.getAbsolutePath());
            }
        }
        return customDir;
    }

    /**
     * 获取应用的私有外部存储目录
     *
     * @param context    上下文
     * @param folderName 自定义文件夹名称
     */
    public static File getPrivateExternalDir(Context context, String folderName) {
        File externalDir = context.getExternalFilesDir(null);
        if (externalDir == null) {
            Log.e(TAG, "External storage not available");
            return null;
        }

        File customDir = new File(externalDir, folderName);

        // 确保目录存在
        if (!customDir.exists()) {
            if (!customDir.mkdirs()) {
                Log.e(TAG, "Failed to create directory: " + customDir.getAbsolutePath());
            }
        }
        return customDir;
    }

    /**
     * 保存数据到外部存储
     *
     * @param context  上下文
     * @param fileName 文件名
     * @param data     数据内容
     * @param isPublic 是否保存到公共目录，私有目录卸载时自动删除
     * @return 是否保存成功
     */
    public static boolean saveToExternalStorage(Context context, String fileName, String data, boolean isPublic) {
        if (!isExternalStorageWritable()) {
            Log.e(TAG, "External storage not writable");
            return false;
        }

        File dir = isPublic ?
                getPublicDocumentsDir(context, "MyFiles") :
                getPrivateExternalDir(context, "MyFiles");

        if (dir == null) return false;

        File file = new File(dir, fileName);

        try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
            writer.write(data);
            Log.d(TAG, "File saved: " + file.getAbsolutePath());
            return true;
        } catch (IOException e) {
            Log.e(TAG, "Error saving file: " + e.getMessage());
            return false;
        }
    }

    /**
     * 从外部存储读取数据
     *
     * @param context  上下文
     * @param fileName 文件名
     * @param isPublic 是否从公共目录读取
     * @return 文件内容，读取失败返回null
     */
    public static String readFromExternalStorage(Context context, String fileName, boolean isPublic) {
        if (!isExternalStorageReadable()) {
            Log.e(TAG, "External storage not readable");
            return null;
        }

        File dir = isPublic ?
                getPublicDocumentsDir(context, "MyFiles") :
                getPrivateExternalDir(context, "MyFiles");

        if (dir == null) return null;

        File file = new File(dir, fileName);

        if (!file.exists()) {
            Log.e(TAG, "File does not exist: " + file.getAbsolutePath());
            return null;
        }

        StringBuilder stringBuilder = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line).append("\n");
            }
            // 删除最后一个换行符
            if (stringBuilder.length() > 0) {
                stringBuilder.deleteCharAt(stringBuilder.length() - 1);
            }
            return stringBuilder.toString();
        } catch (IOException e) {
            Log.e(TAG, "Error reading file: " + e.getMessage());
            return null;
        }
    }

    /**
     * 从外部存储删除文件
     *
     * @param context  上下文
     * @param fileName 文件名
     * @param isPublic 是否从公共目录删除
     * @return 是否删除成功
     */
    public static boolean deleteFromExternalStorage(Context context, String fileName, boolean isPublic) {
        if (!isExternalStorageWritable()) {
            Log.e(TAG, "External storage not writable");
            return false;
        }

        File dir = isPublic ?
                getPublicDocumentsDir(context, "MyFiles") :
                getPrivateExternalDir(context, "MyFiles");

        if (dir == null) return false;

        File file = new File(dir, fileName);

        if (!file.exists()) {
            Log.e(TAG, "File does not exist: " + file.getAbsolutePath());
            return false;
        }

        return file.delete();
    }

    /**
     * 检查文件是否存在
     *
     * @param context  上下文
     * @param fileName 文件名
     * @param isPublic 是否在公共目录
     * @return 文件是否存在
     */
    public static boolean fileExistsInExternalStorage(Context context, String fileName, boolean isPublic) {
        if (!isExternalStorageReadable()) {
            return false;
        }

        File dir = isPublic ?
                getPublicDocumentsDir(context, "MyFiles") :
                getPrivateExternalDir(context, "MyFiles");

        if (dir == null) return false;

        File file = new File(dir, fileName);
        return file.exists();
    }
}
